﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Hi_Baidu.FileShare.Packet.InPacket;
using Hi_Baidu.UI.Compoment;
using Hi_Baidu.Model.ProcessModel;
using Hi_Baidu.FileShare.ListType;
using Hi_Baidu.Packet;

namespace Hi_Baidu.FileShare.Model
{
    public class RequestSendFileModel : Model
    {
        private delegate void DELEGATE_ADD_FILE(SendFileControl sendFileControl);
        private delegate void DELEGATE_CREATE_RECV_FILE(RequestSendFilePacket inpackage);
        private delegate void DELEGATE_CANCLE_SEND_FILE(PassSendFilePacket inpackage);
        private delegate void DELEGATE_ALLOW_SEND_FILE(AllowSendFilePacket inpackage);

        public static void ProcessRequestSendFile(RequestSendFilePacket inpackage)
        {
            //当前没有接收过此文件
            if(!Globle.notifyRecvFileManager.Equals(inpackage.GetFileSession()))
            {
                System.Windows.Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, new DELEGATE_CREATE_RECV_FILE(CreateRecvFile), inpackage);
            }
        }

        /// <summary>
        ///     根据对方的发送文件请求包，创建接收文件对象，并且反映到界面层等待用户选择
        /// </summary>
        /// <param name="inpackage" type="Hi_Baidu.FileShare.Packet.InPacket.RequestSendFilePacket">
        ///     <para>
        ///         发送文件请求包
        ///     </para>
        /// </param>
        private static void CreateRecvFile(RequestSendFilePacket inpackage)
        {
            SendFileControl sendFileControl = new SendFileControl();
            sendFileControl.Key = inpackage.GetFileSession();
            sendFileControl.FileName = inpackage.GetFileName();
            sendFileControl.FileExt = inpackage.GetFileExt();
            sendFileControl.FileSize = inpackage.GetFileSize();
            sendFileControl.FileIcon = IOProcessModel.ConvertToWPF(IOProcessModel.GetIconByFileType("." + inpackage.GetFileExt(), true));
            sendFileControl.SENDF_FILE_SESSION_CODE = inpackage.GetFileSession();
            sendFileControl.UseType = SendFileControl.ControlType.Recv;
            sendFileControl.InPackage = inpackage;
            System.Windows.Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, new DELEGATE_ADD_FILE(Globle.fileShare.CreateFileItem), sendFileControl);
            //创建接收文件记录对象
            TYPE_RecvFileStruct RecvFileStruct = new TYPE_RecvFileStruct(inpackage.GetFileSession());
            RecvFileStruct.FileName = inpackage.GetFileName();
            RecvFileStruct.Ext = inpackage.GetFileExt(); ;
            RecvFileStruct.FileSession = inpackage.GetFileSession();
            RecvFileStruct.FileSize = inpackage.GetFileSize();
            RecvFileStruct.IPAddress = inpackage.GetIPAddress().ToString();
            RecvFileStruct.FilePort = inpackage.GetFilePort();
            RecvFileStruct.Username = inpackage.GetFileSendUsername();
            Globle.notifyRecvFileManager.Add(RecvFileStruct);
        }

        /// <summary>
        ///     回馈拒绝文件的信息包
        /// </summary>
        /// <param name="Username" type="string">
        ///     <para>
        ///         自身用户名
        ///     </para>
        /// </param>
        /// <param name="IPAddress" type="byte[]">
        ///     <para>
        ///         对方IP地址
        ///     </para>
        /// </param>
        /// <param name="FIlePort" type="byte[]">
        ///     <para>
        ///         自身文件传送端口
        ///     </para>
        /// </param>
        /// <param name="Key" type="string">
        ///     <para>
        ///        文件传送会话ID
        ///     </para>
        /// </param>
        /// <param name="FriendFilePort" type="int">
        ///     <para>
        ///        对方文件传送端口
        ///     </para>
        /// </param>
        public static void ProcessUserPassFile(byte[] Username, String IPAddress, byte[] FIlePort, String Key, int FriendFilePort)
        {
            byte[] UsernameLength = BitConverter.GetBytes(Username.Length);
            byte[] PackageBody = new byte[Username.Length + 8];
            int Offset = 0;
            Array.ConstrainedCopy(UsernameLength, 0, PackageBody, Offset, 4);
            Offset += 4;
            Array.ConstrainedCopy(Username, 0, PackageBody, Offset, Username.Length);
            Offset += Username.Length;
            Array.ConstrainedCopy(FIlePort, 0, PackageBody, Offset, 4);
            Offset += 4;

            //向好友发送传送文件请求
            byte[] protocol = ProtocolFactory.ProtocolFactory.GetProtocolFromSendFile
                (
                    "PassSendFile",
                    (int)Protocol.OUT_SendFile.PASS_SEND_FILE,
                    (int)Protocol.NetworkProtocol.TRANSFER_FILE,
                    PackageBody,
                    ProtocolFactory.ProtocolFactory.ACK.Yes,
                    ProtocolFactory.ProtocolFactory.ENCRYPT.No,
                    Key
                 );
            NetControl.Send(protocol, FriendFilePort, IPAddress);
        }

        /// <summary>
        ///     处理接收拒绝文件的回馈
        /// </summary>
        /// <param name="inpackage" type="Hi_Baidu.FileShare.Packet.InPacket.PassSendFilePacket">
        ///     <para>
        ///         拒绝接收文件信息包
        ///     </para>
        /// </param>
        public static void ProcessACKPassSendFIle(PassSendFilePacket inpackage)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, new DELEGATE_CANCLE_SEND_FILE(Globle.fileShare.CancleSendFile), inpackage);
        }
        
        /// <summary>
        ///     向好友发送同意接收文件请求包
        /// </summary>
        /// <param name="Username" type="byte[]">
        ///     <para>
        ///         自身用户名
        ///     </para>
        /// </param>
        /// <param name="IPAddress" type="string">
        ///     <para>
        ///         好友IP
        ///     </para>
        /// </param>
        /// <param name="FIlePort" type="byte[]">
        ///     <para>
        ///         自身文件端口
        ///     </para>
        /// </param>
        /// <param name="Key" type="string">
        ///     <para>
        ///         本次传送文件会话ID
        ///     </para>
        /// </param>
        /// <param name="FriendFilePort" type="int">
        ///     <para>
        ///         好友文件端口
        ///     </para>
        /// </param>
        public static void ProcessAllowSendFile(byte[] Username, String IPAddress, byte[] FIlePort, int FriendFilePort, byte[] MySelfIPAddress, byte[] FileSession)
        {
            byte[] UsernameLength = BitConverter.GetBytes(Username.Length);
            byte[] PackageBody = new byte[Username.Length + FileSession.Length + IPAddress.Length + 16];
            byte[] FileSessionLength = BitConverter.GetBytes(FileSession.Length);
            byte[] IPAddressLength = BitConverter.GetBytes(MySelfIPAddress.Length);
            int Offset = 0;
            Array.ConstrainedCopy(UsernameLength, 0, PackageBody, Offset, 4);
            Offset += 4;
            Array.ConstrainedCopy(Username, 0, PackageBody, Offset, Username.Length);
            Offset += Username.Length;
            Array.ConstrainedCopy(FileSessionLength, 0, PackageBody, Offset, 4);
            Offset += 4;
            Array.ConstrainedCopy(FileSession, 0, PackageBody, Offset, FileSession.Length);
            Offset += FileSession.Length;
            Array.ConstrainedCopy(IPAddressLength, 0, PackageBody, Offset, 4);
            Offset += 4;
            Array.ConstrainedCopy(MySelfIPAddress, 0, PackageBody, Offset, MySelfIPAddress.Length);
            Offset += MySelfIPAddress.Length;
            Array.ConstrainedCopy(FIlePort, 0, PackageBody, Offset, 4);
            Offset += 4;

            //向好友发送传送文件请求
            byte[] protocol = ProtocolFactory.ProtocolFactory.GetProtocolFromSendFile
                (
                    "AllowSendFile",
                    (int)Protocol.OUT_SendFile.ALLOW_SEND_FILE,
                    (int)Protocol.NetworkProtocol.TRANSFER_FILE,
                    PackageBody,
                    ProtocolFactory.ProtocolFactory.ACK.Yes,
                    ProtocolFactory.ProtocolFactory.ENCRYPT.No,
                    Encoding.Default.GetString(FileSession)
                 );
            NetControl.Send(protocol, FriendFilePort, IPAddress);

        }
        
        /// <summary>
        ///     处理接收文件请求
        /// </summary>
        /// <param name="inpackage" type="Hi_Baidu.FileShare.Packet.InPacket.AllowSendFilePacket">
        ///     <para>
        ///         同意接收文件请求包
        ///     </para>
        /// </param>
        public static void ProcessACKAllowSendFile(AllowSendFilePacket inpackage)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, new DELEGATE_ALLOW_SEND_FILE(Globle.fileShare.AllowSendFile), inpackage);
        }
    }
}
